package com.shanzmoo.stm.admin.handler;

import com.shanzmoo.base.bean.SHttpResponse;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.Constant;
import com.shanzmoo.base.constant.ErrorCode;
import com.shanzmoo.base.exception.LogicRepeatCheckException;
import com.shanzmoo.base.util.SExceprtionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 全局异常处理
 *
 * @author: Gzhao 2020/11/12
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object exceptionHandle(Exception exception) {
        log.error("系统异常", exception);

        // 重复校验错误
        if (exception instanceof LogicRepeatCheckException) {
            return SResponse.fail(Constant.ERRCODE_LOGIC, exception.getMessage());
        }

        return SHttpResponse.fail(ErrorCode.SYS_INTERNAL_ERROR);
    }

    /**
     * 接口参数校验异常处理
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Object methodArgumentNotValidExceptionHandle(MethodArgumentNotValidException exception) {
        log.error("接口参数解析异常", exception);

        String errorMsg = SExceprtionUtils.obtainMethodArgumentNotValidExceptionErrorMsg(exception);
        return SHttpResponse.fail(Constant.ERRCODE_PARAM, errorMsg);
    }

    /**
     * security @PreAuthorize 注解抛出AccessDeniedException异常，不会被accessDeniedHandler捕获
     * 增加全局异常捕获
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    @ResponseBody
    public Object accessDeniedExceptionHandle(AccessDeniedException exception) {
        return SResponse.fail(ErrorCode.NOT_AUTHORIZE);
    }

    /**
     * security 校验异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(value = AuthenticationException.class)
    @ResponseBody
    public Object accessDeniedExceptionHandle(AuthenticationException exception) {
        log.error("security 校验异常", exception);
        if (exception instanceof BadCredentialsException) {
            return SHttpResponse.fail(ErrorCode.NOT_AUTH_BADCREDENTIALS);

        } else if (exception instanceof LockedException) {
            return SHttpResponse.fail(ErrorCode.AUTH_LOCKED);

        }
        return SResponse.fail(ErrorCode.NOT_AUTHORIZE);
    }

    /**
     * 自定义系统异常捕捉
     *
     * @author： Gzhao 2021/1/4
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public Object httpRequestMethodNotSupportedExceptionHandle(HttpRequestMethodNotSupportedException exception) {
        log.error("Http请求方异常！！！", exception);
        return SResponse.fail(Constant.ERRCODE_LOGIC, "请确认Http请求方式是否正确");
    }
}
